package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"syscall"
)

func check(er error) {
	if er != nil {
		panic(er)
	}
}

func checkFileIsExist(filename string) bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

func main() {

	var writeString = "hello "
	var filename = "./output1.txt"
	var f *os.File
	var err1 error
	/***************************** 第一种方式: 使用 io.WriteString 写入文件 ***********************************************/
	if checkFileIsExist(filename) {
		f, err1 = os.OpenFile(filename, os.O_RDWR, 0666)
		log.Println("文件存在")
	} else {
		f, err1 = os.Create(filename)
		log.Println("文件不存在")
	}
	check(err1)
	n, err1 := io.WriteString(f, writeString)
	check(err1)
	fmt.Printf("写入 %d 个字节 \n", n)
	/*****************************  第二种方式: 使用 ioutil.WriteFile 写入文件 ***********************************************/
	var d1 = []byte(writeString)
	err2 := ioutil.WriteFile("./output2.txt", d1, 0666)
	check(err2)

	/*****************************  第三种方式:  使用 File(Write,WriteString) 写入文件 ***********************************************/
	f, err3 := os.Create("./output3.txt") //创建文件
	check(err3)
	defer f.Close()
	n2, err3 := f.Write(d1) // 写入 byte
	check(err3)
	fmt.Printf("写入 %d 个字节n", n2)
	n3, err3 := f.WriteString("writesn") //写入文件(字节数组)
	fmt.Printf("写入 %d 个字节n", n3)
	f.Sync()

	/***************************** 第四种方式:  使用 bufio.NewWriter 写入文件 ***********************************************/
	w := bufio.NewWriter(f)
	n4, err3 := w.WriteString("buffer")
	fmt.Printf("写入 %d 个字节n", n4)
	w.Flush() // 必须调用
	f.Close()

}

//输入流复制到文件里面
func test_stdin() error {
	log.Println("***************************** 输入流复制到文件里面 *****************************")
	var out io.Writer
	var in io.Reader
	in = os.NewFile(uintptr(syscall.Stdin), "/dev/stdin")
	out, _ = os.OpenFile("./env.txt", os.O_RDWR, 0666)
	n, err := io.Copy(out, in)
	fmt.Printf("\nwrite %d err %v \n", n, err)
	return err

}

//文件里面复制到输出流
func test_stdout() error {
	log.Println("***************************** 文件里面复制到输出流 *****************************")
	var out io.Writer
	var in io.Reader
	out = os.NewFile(uintptr(syscall.Stdout), "/dev/stdin")
	in, _ = os.OpenFile("./output1.txt", os.O_RDWR, 0666) // 必须文件事先存在
	n, err := io.Copy(out, in)

	fmt.Printf("\nwrite %d err %v \n", n, err)

	return err
}

var USER_AGENT string
var client = &http.Client{}

func doRequest(c *http.Client, req *http.Request) (*http.Response, error) {
	req.Header.Set("User-Agent", USER_AGENT)
	resp, err := c.Do(req)
	return resp, err
}
func BytesCombine(pBytes ...[]byte) []byte {
	len := len(pBytes)
	s := make([][]byte, len)
	for index := 0; index < len; index++ {
		s[index] = pBytes[index]
	}
	sep := []byte("")
	return bytes.Join(s, sep)
}

//从 http 链接中读取
func test_stdin_http(file string) {
	log.Println("***************************** 从 http 链接中读取 *****************************")
	out, err := os.Create(file)
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()
	urls := []string{
		"http://www.baidu.com",
		"http://www.whatdy.com",
	}
	for _, v := range urls {
		req, err := http.NewRequest("GET", v, nil)
		if err != nil {
			log.Fatal(err)
		}
		resp, err := doRequest(client, req)
		if err != nil {
			log.Print(err)
			continue
		}
		if resp.StatusCode != 200 {
			log.Printf("Received HTTP %v for %v\n", resp.StatusCode, v)
			continue
		}
		//////// 数据追加或者解密
		// ReadCloser => byte => 加工 => ReadCloser
		bodyBytes, _ := ioutil.ReadAll(resp.Body)
		bodyBytes = BytesCombine(bodyBytes, []byte("===>"))
		resp.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
		///
		_, err = io.Copy(out, resp.Body)
		if err != nil {
			log.Fatal(err)
		}
		resp.Body.Close()
	}
}
